using System;
using System.Collections.ObjectModel;
using System.Windows.Automation;
using ProdControls.UIAPatterns;
using ProdLogging;

/* Notes
 * -Tree-
 * Supported Patterns: 
 * ISelectionProvider
 * IScrollProvider 
 * 
 * Proposed functionality:
 * 
 * -Tree Item (node)-
 * IInvokeProvider 
 * IExpandCollapseProvider
 * ISelectionItemProvider 
 * IToggleProvider 
 */

namespace ProdControls
{
    /// <summary>
    ///   Methods to work with TreeView controls using the UI Automation framework
    /// </summary>
    public sealed class ProdTreeView : BaseProdControl
    {
        private int _chk;
        private int _treeIndex;

        /// <summary>
        ///   holds all tree nodes.
        /// </summary>
        internal Collection<AutomationElement> AllNodes { get; private set; }

        #region Constructors

        /// <summary>
        ///   Initializes a new instance of the ProdTreeView class.
        /// </summary>
        /// <param name="prodWindow"> The ProdWindow that contains this control. </param>
        /// <param name="automationId"> The UI Automation element </param>
        /// <remarks>
        ///   Will attempt to match AutomationId, then ReadOnly
        /// </remarks>
        public ProdTreeView(ProdWindow prodWindow, string automationId)
            : base(prodWindow, automationId)
        {
            AllNodes = new Collection<AutomationElement>();
            AutomationElement aeNode = TreeWalker.ControlViewWalker.GetFirstChild(UiaElement);
            EnumControlElements(aeNode);
        }

        /// <summary>
        ///   Initializes a new instance of the ProdTreeView class.
        /// </summary>
        /// <param name="prodWindow"> The ProdWindow that contains this control. </param>
        /// <param name="treePosition"> The index of this control in the parent windows UI control tree. </param>
        public ProdTreeView(ProdWindow prodWindow, int treePosition)
            : base(prodWindow, treePosition)
        {
        }

        /// <summary>
        ///   Initializes a new instance of the ProdTreeView class.
        /// </summary>
        /// <param name="controlHandle"> Window handle of the control </param>
        public ProdTreeView(IntPtr controlHandle)
            : base(controlHandle)
        {
        }

        #endregion

        /// <summary>
        ///   Enumerates all nodes ion the TreeView and adds to a collection
        /// </summary>
        /// <param name="aeRoot"> The root tree node. </param>
        private void EnumControlElements(AutomationElement aeRoot)
        {
            while (aeRoot != null)
            {
                AllNodes.Add(aeRoot);
                _chk++;
                int ret = ExpandCollapseHelper.Expand(aeRoot);
                if (ret == -1)
                {
                    ExpandCollapseHelper.Collapse(AllNodes[_treeIndex]);
                    aeRoot = TreeWalker.ControlViewWalker.GetNextSibling(AllNodes[_treeIndex]);
                    _treeIndex = _chk;
                }
                else
                {
                    aeRoot = TreeWalker.ControlViewWalker.GetFirstChild(aeRoot);
                }
                EnumControlElements(aeRoot);
                aeRoot = null;
            }

            return;
        }

        /// <summary>
        ///   Gets the number of items in the tree
        /// </summary>
        /// <returns> The number of items in the tree </returns>
        /// <remarks>
        ///   because nodes don't exist until
        /// </remarks>
        [ProdLogging(LoggingLevels.Prod, VerbositySupport = LoggingVerbosity.Minimum)]
        public int GetNodeCount()
        {
            return AllNodes.Count;
        }

        /// <summary>
        ///   The Default invoke action.
        /// </summary>
        /// <param name="index"> The index. </param>
        /// <returns> </returns>
        public AutomationElement DefaultAction(int index)
        {
            return AllNodes[index];
        }
    }
}